#include<iostream>
#include<memory>
#include<unordered_map>
#include<functional>
#include<unistd.h>

using Task_func=std::function<void()>;
using Release_Func=std::function<void()>;

class TimerTask
{
    public:
    TimerTask(uint64_t id,uint32_t timeout,const Task_func& cb):_id(id),_timeout(timeout),_task(cb){}
    void Set_Release(const Release_Func& release)
    {
        _release=release;
    }
    ~TimerTask()
    {
        if(_canceled==false)
            _task();
        _release();
    }
    uint32_t GetTimeOut()
    {
        return _timeout;
    }
    void Cancel()
    {
        _canceled=true;
    }
    private:
    uint64_t _id;//唯一的定时器id
    uint32_t _timeout;//定时器超时时间
    Task_func _task;
    Release_Func _release;
    bool _canceled=false;
};

class TimerWheel
{
    public:
    //weakptr与sharedptr不能类型强转，sharedptr可以用来构造weakptr，因为weakptr是作为观察者
    //weakptr不能用来构造sharedptr，但是可以使用对应的lock接口来获取weakptr观察的sharedptr对象
    using shared_task=std::shared_ptr<TimerTask>;
    using weak_task=std::weak_ptr<TimerTask>;

    TimerWheel():_capacity(60),_tick(0),_wheel(_capacity){}
    void time_add(uint64_t id,uint32_t timeout,const Task_func& cb)
    {
        shared_task new_task(new TimerTask(id,timeout,cb));
        auto remove=std::bind(&TimerWheel::Reomve_Timer,this,id);
        new_task->Set_Release(remove);
        _map[id]=weak_task(new_task);
        _wheel[(_tick+new_task->GetTimeOut())%_capacity].emplace_back(new_task);
    }
    void time_refresh(uint64_t id)
    {
        shared_task new_task(_map[id].lock());
        _wheel[(_tick+new_task->GetTimeOut())%_capacity].emplace_back(new_task);
    }

    void RunTask()
    {
        _tick=(_tick+1)%_capacity;
        _wheel[_tick].clear();//clear接口可以释放数组中的所有对象
    }
    void CancleTask(uint64_t id)
    {
        _map[id].lock()->Cancel();
    }
    private:
    void Reomve_Timer(uint64_t id)
    {
        auto timers=_map.find(id);
        if(timers!=_map.end())
            _map.erase(timers);
    }

    private:

    int _capacity;
    int _tick;
    std::vector<std::vector<shared_task>> _wheel;
    std::unordered_map<uint64_t,weak_task> _map;
};

class test
{
    public:
    test()
    {
        std::cout<<"构造"<<std::endl;
    }
    ~test()
    {
        std::cout<<"析构"<<std::endl;
        exit(0);
    }
};
void DelTest(test* _test)
{
    delete _test;
}
int main()
{
    TimerWheel tw;
    test* _test=new test();
    auto func=std::bind(DelTest,_test);
    tw.time_add(888,5,func);
    for(int i=0;i<5;++i)
    {
        tw.time_refresh(888);
        tw.RunTask();
        std::cout<<"刷新"<<std::endl;
        sleep(1);
    }
    tw.CancleTask(888);
    std::cout<<"取消任务，等待几秒"<<std::endl;
    sleep(5);
}